home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
misc
/
sci
/
ephem_src_4_28.lha
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-28
|
26KB
|
1,049 lines
/* main "ephem" program.
* -------------------------------------------------------------------
* Copyright (c) 1990,1991,1992 by Elwood Charles Downey
*
* Permission is granted to make and distribute copies of this program
* free of charge, provided the copyright notice and this permission
* notice are preserved on all copies. All other rights reserved.
* -------------------------------------------------------------------
* set options.
* init screen and circumstances.
* enter infinite loop updating screen and allowing operator input.
*/
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
#include <math.h>
#ifdef VMS
#include <stdlib.h>
#endif
#include "astro.h"
#include "circum.h"
#include "screen.h"
extern char *strncpy();
#ifdef AMIGA
extern char *wgetenv();
#else
extern char *getenv();
#endif
/* shorthands for fields of a Now structure, now.
* first undo the ones for a Now pointer from circum.h.
*/
#undef mjd
#undef lat
#undef lng
#undef tz
#undef temp
#undef pressure
#undef height
#undef epoch
#undef tznm
#define mjd now.n_mjd
#define lat now.n_lat
#define lng now.n_lng
#define tz now.n_tz
#define temp now.n_temp
#define pressure now.n_pressure
#define height now.n_height
#define epoch now.n_epoch
#define tznm now.n_tznm
static jmp_buf fpe_err_jmp; /* used to recover from SIGFPE */
static char *cfgfile; /* !0 if -c used */
#ifdef AMIGA
static char cfgdef[] = "S:ephem.cfg"; /* default configuration file name */
#else
static char cfgdef[] = "ephem.cfg"; /* default configuration file name */
#endif
static Now now; /* where when and how, right now */
static double tminc; /* hrs to inc time by each loop; RTC means use clock */
static int nstep; /* steps to go before stopping */
static int spause; /* secs to pause between steps */
static int optwi; /* set when want to display dawn/dusk/len-of-night */
static int oppl; /* mask of (1<<planet) bits; set when want to show it */
main (ac, av)
int ac;
char *av[];
{
void bye();
void on_fpe();
static char freerun[] =
"Running... press any key to stop to make changes.";
static char prmpt[] =
"Move to another field, RETURN to change this field, ? for help, or q to run";
static char hlp[] =
"arrow keys move to field; any key stops running; ^d exits; ^l redraws";
int fld = rcfpack(R_NSTEP, C_NSTEPV, 0); /* initial cursor loc */
int sflag = 0; /* not silent, by default */
int one = 1; /* use a variable so optimizer doesn't get disabled */
int srchdone = 0; /* true when search funcs say so */
int newcir = 2; /* set when circumstances change - means don't tminc */
while ((--ac > 0) && (**++av == '-')) {
char *s;
for (s = *av+1; *s != '\0'; s++)
switch (*s) {
case 's': /* no credits "silent" (don't publish this) */
sflag++;
break;
case 'c': /* set name of config file to use */
if (--ac <= 0) usage("-c but no config file");
cfgfile = *++av;
break;
case 'd': /* set alternate database file name */
if (--ac <= 0) usage("-d but no database file");
obj_setdbfilename (*++av);
break;
default:
usage("Bad - option");
}
}
if (!sflag)
credits();
/* fresh screen.
* crack config file, THEN args so args may override.
*/
c_erase();
read_cfgfile ();
read_fieldargs (ac, av);
/* set up to clean up screen and tty if interrupted.
* also set up to stop if get floating error.
*/
(void) signal (SIGINT, bye);
(void) signal (SIGFPE, on_fpe);
/* update screen forever (until QUIT) */
while (one) {
/* if get a floating error, longjmp() here and stop looping */
if (setjmp (fpe_err_jmp))
nstep = 0;
else {
nstep -= 1;
/* recalculate everything and update all the fields */
redraw_screen (newcir);
mm_newcir (0);
/* let searching functions change tminc and check for done */
srchdone = srch_eval (mjd, &tminc) < 0;
print_tminc(0); /* to show possibly new search increment */
/* update plot and listing files, now that all fields are up
* to date and search function has been evaluated.
*/
plot();
listing();
/* handle spause if we are really looping */
if (nstep > 0)
slp_sync();
}
/* stop loop to allow op to change parameters:
* if a search evaluation converges (or errors out),
* or if steps are done,
* or if op hits any key.
*/
newcir = 0;
if (srchdone || nstep <= 0 || (chk_char()==0 && read_char()!=0)) {
int nfld;
/* update screen with the current stuff if stopped during
* unattended plotting or listing since last redraw_screen()
* didn't.
*/
if ((plot_ison() || listing_ison()) && nstep > 0)
redraw_screen (1);
/* return nstep to default of 1 */
if (nstep <= 0) {
nstep = 1;
print_nstep (0);
}
/* change fields until END.
* update all time fields if any are changed
* and print NEW CIRCUMSTANCES if any have changed.
* QUIT causes bye() to be called and we never return.
*/
while(nfld = sel_fld(fld,alt_menumask()|F_CHG,prmpt,hlp)) {
if (chg_fld ((char *)0, &nfld)) {
mm_now (&now, 1);
mm_newcir(1);
newcir = 1;
}
fld = nfld;
}
if (nstep > 1)
f_prompt (freerun);
}
/* increment time only if op didn't change cirumstances */
if (!newcir)
inc_mjd (&now, tminc);
}
return (0);
}
/* read in ephem's configuration file, if any.
* if errors in file, call usage() (which exits).
* if use -d, require it; else try $EPHEMCFG and ephem.cfg but don't
* complain if can't find these since, after all, one is not required.
* skip all lines that doesn't begin with an alpha char.
*/
static
read_cfgfile()
{
char buf[128];
FILE *fp;
char *fn;
/* open the config file.
* only REQUIRED if used -d option.
* if succcessful, fn points to file name.
*/
if (cfgfile) {
fn = cfgfile;
fp = fopen (fn, "r");
if (!fp) {
(void) sprintf (buf, "Can not open %s", fn);
usage (buf); /* does not return */
}
} else {
#ifdef AMIGA
fn = wgetenv ("EPHEMCFG");
#else
fn = getenv ("EPHEMCFG");
#endif
if (!fn)
fn = cfgdef;
}
fp = fopen (fn, "r");
if (!fp)
return; /* oh well; after all, it's not required */
while (fgets (buf, sizeof(buf), fp)) {
if (!isalpha(buf[0]))
continue;
buf[strlen(buf)-1] = '\0'; /* discard trailing \n */
if (crack_fieldset (buf) < 0) {
char why[NC];
(void) sprintf (why, "Bad field spec in %s: %s\n", fn, buf);
usage (why);
}
}
(void) fclose (fp);
}
/* draw all the stuff on the screen, using the current menu.
* if how_much == 0 then just update fields that need it;
* if how_much == 1 then redraw all fields;
* if how_much == 2 then erase the screen and redraw EVERYTHING.
*/
redraw_screen (how_much)
int how_much;
{
if (how_much == 2)
c_erase();
/* print the single-step message if this is the last loop */
if (nstep < 1)
print_updating();
if (how_much == 2) {
mm_borders();
mm_labels();
srch_prstate(1);
plot_prstate(1);
listing_prstate(1);
}
/* if just updating changed fields while plotting or listing
* unattended then suppress most screen updates except
* always show nstep to show plot loops to go and
* always show tminc to show search convergence progress.
*/
print_nstep(how_much);
print_tminc(how_much);
print_spause(how_much);
if (how_much == 0 && (plot_ison() || listing_ison()) && nstep > 0)
f_off();
/* print all the time-related fields */
mm_now (&now, how_much);
if (optwi)
mm_twilight (&now, how_much);
/* print stuff on bottom menu */
print_alt (how_much);
f_on();
}
/* clean up and exit.
*/
void
bye()
{
c_erase();
byetty();
exit (0);
}
/* this gets called when a floating point error occurs.
* we force a jump back into main() with looping terminated.
*/
static
void
on_fpe()
{
extern void longjmp();
(void) signal (SIGFPE, on_fpe);
f_msg ("Floating point error has occurred - computations aborted.");
longjmp (fpe_err_jmp, 1);
}
usage(why)
char *why;
{
/* don't advertise -s (silent) option */
c_erase();
f_string (1, 1, why);
f_string (2, 1,
"usage: [-c <configfile>] [-d <database>] [field=value ...]\r\n");
byetty();
exit (1);
}
/* process the field specs from the command line.
* if trouble call usage() (which exits).
*/
static
read_fieldargs (ac, av)
int ac; /* number of such specs */
char *av[]; /* array of strings in form <field_name value> */
{
while (--ac >= 0) {
char *fs = *av++;
if (crack_fieldset (fs) < 0) {
char why[NC];
(void) sprintf (why, "Bad command line spec: %.*s",
sizeof(why)-26, fs);
usage (why);
}
}
}
/* process a field spec in buf, either from config file or argv.
* return 0 if recognized ok, else -1.
*/
static
crack_fieldset (buf)
char *buf;
{
#define ARRAY_SIZ(a) (sizeof(a)/sizeof((a)[0]))
#define MAXKW 6 /* longest keyword, not counting trailing 0 */
/* N.B. index of item is its case value, below.
* N.B. if add an item, keep it no longer than MAXKW chars.
*/
static char keywords[][MAXKW+1] = {
/* 0 */ "LAT",
/* 1 */ "LONG",
/* 2 */ "UT",
/* 3 */ "UD",
/* 4 */ "TZONE",
/* 5 */ "TZNAME",
/* 6 */ "HEIGHT",
/* 7 */ "NSTEP",
/* 8 */ "PAUSE",
/* 9 */ "STPSZ",
/* 10 */ "TEMP",
/* 11 */ "PRES",
/* 12 */ "EPOCH",
/* 13 */ "JD",
/* 14 */ "OBJX",
/* 15 */ "OBJY",
/* 16 */ "PROPTS",
/* 17 */ "MENU"
};
int i;
int l;
int f;
for (i = 0; i < ARRAY_SIZ(keywords); i++)
if (strncmp (keywords[i], buf, l = strlen(keywords[i])) == 0) {
buf += l+1; /* skip keyword and its subsequent delimiter */
break;
}
switch (i) {
case 0: f = rcfpack (R_LAT,C_LATV,0); (void) chg_fld (buf, &f);
break;
case 1: f = rcfpack (R_LONG,C_LONGV,0), (void) chg_fld (buf, &f);
break;
case 2: f = rcfpack (R_UT,C_UTV,0), (void) chg_fld (buf, &f);
break;
case 3: f = rcfpack (R_UD,C_UD,0), (void) chg_fld (buf, &f);
break;
case 4: f = rcfpack (R_TZONE,C_TZONEV,0), (void) chg_fld (buf, &f);
break;
case 5: f = rcfpack (R_TZN,C_TZN,0), (void) chg_fld (buf, &f);
break;
case 6: f = rcfpack (R_HEIGHT,C_HEIGHTV,0), (void) chg_fld (buf, &f);
break;
case 7: f = rcfpack (R_NSTEP,C_NSTEPV,0), (void) chg_fld (buf, &f);
break;
case 8: f = rcfpack (R_PAUSE,C_PAUSEV,0), (void) chg_fld (buf, &f);
break;
case 9: f = rcfpack (R_STPSZ,C_STPSZV,0), (void) chg_fld (buf, &f);
break;
case 10: f = rcfpack (R_TEMP,C_TEMPV,0), (void) chg_fld (buf, &f);
break;
case 11: f = rcfpack (R_PRES,C_PRESV,0), (void) chg_fld (buf, &f);
break;
case 12: f = rcfpack (R_EPOCH,C_EPOCHV,0), (void) chg_fld (buf, &f);
break;
case 13: f = rcfpack (R_JD,C_JDV,0), (void) chg_fld (buf, &f);
break;
case 14: (void) obj_filelookup (OBJX, buf);
break;
case 15: (void) obj_filelookup (OBJY, buf);
break;
case 16:
if (buf[-1] != '+')
optwi = oppl = 0;
while (*buf)
switch (*buf++) {
case 'T': optwi = 1; break;
case 'S': oppl |= (1<<SUN); break;
case 'M': oppl |= (1<<MOON); break;
case 'e': oppl |= (1<<MERCURY); break;
case 'v': oppl |= (1<<VENUS); break;
case 'm': oppl |= (1<<MARS); break;
case 'j': case 'J': oppl |= (1<<JUPITER); break;
case 's': oppl |= (1<<SATURN); break;
case 'u': oppl |= (1<<URANUS); break;
case 'n': oppl |= (1<<NEPTUNE); break;
case 'p': oppl |= (1<<PLUTO); break;
case 'x': oppl |= (1<<OBJX); obj_on(OBJX); break;
case 'y': oppl |= (1<<OBJY); obj_on(OBJY); break;
}
break;
case 17:
if (strncmp (buf, "DATA", 4) == 0)
altmenu_init (F_MNU1);
else if (strncmp (buf, "RISET", 5) == 0)
altmenu_init (F_MNU2);
else if (strncmp (buf, "SEP", 3) == 0)
altmenu_init (F_MNU3);
else if (strncmp (buf, "JUP", 3) == 0)
altmenu_init (F_MNUJ);
break;
default:
return (-1);
}
return (0);
}
/* react to the field at *fld according to the optional string input at bp.
* if bp is != 0 use it, else issue read_line() and use buffer.
* then sscanf the buffer and update the corresponding (global) variable(s)
* or do whatever a pick at that field should do.
* we might also change *fld if we want to change the current cursor location.
* return 1 if we change a field that invalidates any of the times or
* to update all related fields.
*/
static
chg_fld (bp, fld)
char *bp;
int *fld;
{
char buf[NC];
int deghrs = 0, mins = 0, secs = 0;
int new = 0;
/* switch on just the row/col portion */
switch (unpackrc(*fld)) {
case rcfpack (R_ALTM, C_ALTM, 0):
if (altmenu_setup() == 0) {
print_updating();
alt_erase();
print_alt(2);
}
break;
case rcfpack (R_JD, C_JDV, 0):
if (!bp) {
static char p[] = "Julian Date (or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else
mjd = atof(bp) - 2415020L;
set_t0 (&now);
new = 1;
break;
case rcfpack (R_UD, C_UD, 0):
if (!bp) {
static char p[] = "utc date (m/d/y, or year.d, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
if (decimal_year(bp)) {
double y = atof (bp);
year_mjd (y, &mjd);
} else {
double day, newmjd0;
int month, year;
mjd_cal (mjd, &month, &day, &year); /* init with now */
f_sscandate (bp, &month, &day, &year);
cal_mjd (month, day, year, &newmjd0);
/* if don't give a fractional part to days
* then retain current hours.
*/
if ((long)day == day)
mjd = newmjd0 + mjd_hr(mjd)/24.0;
else
mjd = newmjd0;
}
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_UT, C_UTV, 0):
if (!bp) {
static char p[] = "utc time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double newutc = (mjd-mjd_day(mjd)) * 24.0;
f_dec_sexsign (newutc, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newutc);
mjd = mjd_day(mjd) + newutc/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LD, C_LD, 0):
if (!bp) {
static char p[] = "local date (m/d/y, or year.d, n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
if (decimal_year(bp)) {
double y = atof (bp);
year_mjd (y, &mjd);
mjd += tz/24.0;
} else {
double day, newlmjd0;
int month, year;
mjd_cal (mjd-tz/24.0, &month, &day, &year); /* now */
f_sscandate (bp, &month, &day, &year);
cal_mjd (month, day, year, &newlmjd0);
/* if don't give a fractional part to days
* then retain current hours.
*/
if ((long)day == day)
mjd = newlmjd0 + mjd_hr(mjd-tz/24.0)/24.0;
else
mjd = newlmjd0;
mjd += tz/24.0;
}
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LT, C_LT, 0):
if (!bp) {
static char p[] = "local time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double newlt = (mjd-mjd_day(mjd)) * 24.0 - tz;
range (&newlt, 24.0);
f_dec_sexsign (newlt, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &newlt);
mjd = mjd_day(mjd-tz/24.0) + (newlt + tz)/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_LST, C_LSTV, 0):
if (!bp) {
static char p[] = "local sidereal time (h:m:s, or n for Now): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'n' || bp[0] == 'N')
time_fromsys (&now);
else {
double lst, utc;
now_lst (&now, &lst);
f_dec_sexsign (lst, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lst);
lst -= radhr(lng); /* convert to gst */
range (&lst, 24.0);
gst_utc (mjd_day(mjd), lst, &utc);
mjd = mjd_day(mjd) + utc/24.0;
}
set_t0 (&now);
new = 1;
break;
case rcfpack (R_TZN, C_TZN, 0):
if (!bp) {
static char p[] = "timezone abbreviation (3 char max): ";
f_prompt (p);
if (read_line (buf, 3) <= 0)
break;
bp = buf;
}
(void) strncpy (tznm, bp, sizeof(tznm)-1);
new = 1;
break;
case rcfpack (R_TZONE, C_TZONEV, 0):
if (!bp) {
static char p[] = "hours behind utc: ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (tz, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tz);
new = 1;
break;
case rcfpack (R_LONG, C_LONGV, 0):
if (!bp) {
static char p[] = "longitude (+ west) (d:m:s): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (-raddeg(lng), °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lng);
lng = degrad (-lng); /* want - radians west */
new = 1;
break;
case rcfpack (R_LAT, C_LATV, 0):
if (!bp) {
static char p[] = "latitude (+ north) (d:m:s): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
f_dec_sexsign (raddeg(lat), °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &lat);
lat = degrad (lat);
new = 1;
break;
case rcfpack (R_HEIGHT, C_HEIGHTV, 0):
if (!bp) {
static char p[] = "height above sea level (ft): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (sscanf (bp, "%lf", &height) == 1) {
height /= 2.093e7; /*convert ft to earth radii above sea level*/
new = 1;
}
break;
case rcfpack (R_NSTEP, C_NSTEPV, 0):
if (!bp) {
static char p[] = "number of steps to run: ";
f_prompt (p);
if (read_line (buf, 8) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%d", &nstep);
print_nstep (0);
break;
case rcfpack (R_PAUSE, C_PAUSEV, 0):
if (!bp) {
static char p[] = "seconds to pause between steps: ";
f_prompt (p);
if (read_line (buf, 8) <= 0)
break;
bp = buf;
}
(void) sscanf (bp, "%d", &spause);
print_spause (0);
break;
case rcfpack (R_TEMP, C_TEMPV, 0):
if (!bp) {
static char p[] = "temperature (deg.F): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (sscanf (bp, "%lf", &temp) == 1) {
temp = 5./9.*(temp - 32.0); /* want degs C */
new = 1;
}
break;
case rcfpack (R_PRES, C_PRESV, 0):
if (!bp) {
static char p[] =
"atmos pressure (in. Hg; 0 for no refraction correction): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (sscanf (bp, "%lf", &pressure) == 1) {
pressure *= 33.86; /* want mBar */
new = 1;
}
break;
case rcfpack (R_EPOCH, C_EPOCHV, 0):
if (!bp) {
static char p[] = "epoch (year, or e for Equinox of Date): ";
f_prompt (p);
if (read_line (buf, PW-strlen(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'e' || bp[0] == 'E')
epoch = EOD;
else {
double e;
e = atof(bp);
year_mjd (e, &epoch);
}
new = 1;
break;
case rcfpack (R_STPSZ, C_STPSZV, 0):
if (!bp) {
static char p[] =
"step size increment (h:m:s, or <x>d for x days, or r for RTC): ";
f_prompt (p);
if (read_line (buf, PW-sizeof(p)) <= 0)
break;
bp = buf;
}
if (bp[0] == 'r' || bp[0] == 'R')
tminc = RTC;
else {
int last = strlen (bp) - 1;
if (bp[last] == 'd') {
/* ends in d so treat as a number of days */
double x;
if (sscanf (bp, "%lf", &x) == 1)
tminc = x * 24.0;
} else {
if (tminc == RTC)
deghrs = mins = secs = 0;
else
f_dec_sexsign (tminc, °hrs, &mins, &secs);
f_sscansex (bp, °hrs, &mins, &secs);
sex_dec (deghrs, mins, secs, &tminc);
}
}
print_tminc(0);
set_t0 (&now);
break;
case rcfpack (R_PLOT, C_PLOT, 0):
plot_setup();
if (plot_ison())
new = 1;
break;
case rcfpack (R_LISTING, C_LISTING, 0):
listing_setup();
if (listing_ison())
new = 1;
break;
case rcfpack (R_WATCH, C_WATCH, 0):
watch (&now, tminc, oppl);
/* set new reference time to what watch left it.
* no need to set new since watch just did a redraw.
*/
set_t0 (&now);
break;
case rcfpack (R_DAWN, C_DAWN, 0):
case rcfpack (R_DUSK, C_DUSK, 0):
case rcfpack (R_LON, C_LON, 0):
if (optwi ^= 1) {
print_updating();
mm_twilight (&now, 1);
} else {
f_blanks (R_DAWN, C_DAWNV, 5);
f_blanks (R_DUSK, C_DUSKV, 5);
f_blanks (R_LON, C_LONV, 5);
}
break;
case rcfpack (R_SRCH, C_SRCH, 0):
srch_setup();
if (srch_ison())
new = 1;
break;
case rcfpack (R_SUN, C_OBJ, 0):
toggle_body (SUN);
break;
case rcfpack (R_SUN, C_CONSTEL, 0):
if (oppl & (1<<SUN))
constellation_msg (SUN, &now);
break;
case rcfpack (R_MOON, C_OBJ, 0):
toggle_body (MOON);
break;
case rcfpack (R_MOON, C_CONSTEL, 0):
if (oppl & (1<<MOON))
constellation_msg (MOON, &now);
break;
case rcfpack (R_MERCURY, C_OBJ, 0):
toggle_body (MERCURY);
break;
case rcfpack (R_MERCURY, C_CONSTEL, 0):
if (oppl & (1<<MERCURY))
constellation_msg (MERCURY, &now);
break;
case rcfpack (R_VENUS, C_OBJ, 0):
toggle_body (VENUS);
break;
case rcfpack (R_VENUS, C_CONSTEL, 0):
if (oppl & (1<<VENUS))
constellation_msg (VENUS, &now);
break;
case rcfpack (R_MARS, C_OBJ, 0):
toggle_body (MARS);
break;
case rcfpack (R_MARS, C_CONSTEL, 0):
if (oppl & (1<<MARS))
constellation_msg (MARS, &now);
break;
case rcfpack (R_JUPITER, C_OBJ, 0):
toggle_body (JUPITER);
break;
case rcfpack (R_JUPITER, C_CONSTEL, 0):
if (oppl & (1<<JUPITER))
constellation_msg (JUPITER, &now);
break;
case rcfpack (R_JUPITER, C_XTRA, 0):
if (oppl & (1<<JUPITER)) {
print_updating();
alt_erase();
altmenu_init (F_MNUJ);
print_alt (2);
*fld = rcfpack(R_NSTEP, C_NSTEPV, 0);
}
break;
case rcfpack (R_SATURN, C_OBJ, 0):
toggle_body (SATURN);
break;
case rcfpack (R_SATURN, C_CONSTEL, 0):
if (oppl & (1<<SATURN))
constellation_msg (SATURN, &now);
break;
case rcfpack (R_URANUS, C_OBJ, 0):
toggle_body (URANUS);
break;
case rcfpack (R_URANUS, C_CONSTEL, 0):
if (oppl & (1<<URANUS))
constellation_msg (URANUS, &now);
break;
case rcfpack (R_NEPTUNE, C_OBJ, 0):
toggle_body (NEPTUNE);
break;
case rcfpack (R_NEPTUNE, C_CONSTEL, 0):
if (oppl & (1<<NEPTUNE))
constellation_msg (NEPTUNE, &now);
break;
case rcfpack (R_PLUTO, C_OBJ, 0):
toggle_body (PLUTO);
break;
case rcfpack (R_PLUTO, C_CONSTEL, 0):
if (oppl & (1<<PLUTO))
constellation_msg (PLUTO, &now);
break;
case rcfpack (R_OBJX, C_OBJ, 0):
/* this might change which columns are used so erase all when
* returns and redraw if still on.
*/
obj_setup (OBJX);
alt_nobody (OBJX);
if (obj_ison (OBJX)) {
oppl |= 1 << OBJX;
print_updating();
alt_body (OBJX, 1, &now);
} else
oppl &= ~(1 << OBJX); /* already erased; just clear flag */
break;
case rcfpack (R_OBJX, C_CONSTEL, 0):
if (oppl & (1<<OBJX))
constellation_msg (OBJX, &now);
break;
case rcfpack (R_OBJY, C_OBJ, 0):
/* this might change which columns are used so erase all when
* returns and redraw if still on.
*/
obj_setup (OBJY);
alt_nobody (OBJY);
if (obj_ison (OBJY)) {
oppl |= 1 << OBJY;
print_updating();
alt_body (OBJY, 1, &now);
} else
oppl &= ~(1 << OBJY); /* already erased; just clear flag */
break;
case rcfpack (R_OBJY, C_CONSTEL, 0):
if (oppl & (1<<OBJY))
constellation_msg (OBJY, &now);
break;
}
return (new);
}
static
print_tminc(force)
int force;
{
static double last = -123.456; /* anything unlikely */
if (force || tminc != last) {
if (tminc == RTC)
f_string (R_STPSZ, C_STPSZV, " RT CLOCK");
else if (fabs(tminc) >= 24.0)
f_double (R_STPSZ, C_STPSZV, "%6.4g dy", tminc/24.0);
else
f_signtime (R_STPSZ, C_STPSZV, tminc);
last = tminc;
}
}
/* print stuff on bottom menu */
static
print_alt (howmuch)
int howmuch;
{
if (howmuch == 2)
alt_labels();
if (alt_menumask() == F_MNUJ)
altj_display (howmuch, &now);
else {
int p;
for (p = nxtbody(-1); p != -1; p = nxtbody(p))
if (oppl & (1<<p))
alt_body (p, howmuch, &now);
}
}
print_updating()
{
f_prompt ("Updating...");
}
static
print_nstep(force)
int force;
{
static int last;
if (force || nstep != last) {
char buf[16];
(void) sprintf (buf, "%8d", nstep);
f_string (R_NSTEP, C_NSTEPV, buf);
last = nstep;
}
}
static
print_spause(force)
int force;
{
static int last;
if (force || spause != last) {
char buf[16];
(void) sprintf (buf, "%8d", spause);
f_string (R_PAUSE, C_PAUSEV, buf);
last = spause;
}
}
/* if not plotting/listing/searching then sleep spause seconds.
* if time is being based on the real-time clock, sync on the next
* integral multiple of spause seconds after the minute.
* check for keyboard action once each second to let it break out early.
*/
slp_sync()
{
extern long time();
if (spause > 0 && !plot_ison() && !srch_ison() && !listing_ison()) {
int n;
if (tminc == RTC) {
long t;
(void) time (&t);
n = spause - (t % spause);
} else
n = spause;
while (--n >= 0)
if (chk_char() == 0)
break;
else
(void) sleep (1);
}
}
static
toggle_body (p)
int p;
{
if ((oppl ^= (1<<p)) & (1<<p)) {
print_updating();
alt_body (p, 1, &now);
} else
alt_nobody (p);
}